package vm


import "api"


// 加载类指令


// LOADNIL指令(iABC模式)用于给连续n个寄存器放置nil值
// 寄存器的起始索引由操作数A指定
// 寄存器的数量则由操作数B指定
// 操作数C没有用
// 在Lua代码里，局部变量的默认初始值是nil
// LOADNIL指令常用于给连续n个局部变量设置初始值
// R(A), R(A+1), ... , R(A+B) := nil
func loadNil(i Instruction, vm api.LuaVM) {

	a, b, _ := i.ABC()
	a += 1  // 寄存器数值作为栈索引时需要+1

	vm.PushNil()
	for i := a; i <= a+b; i++ {
		vm.Copy(-1, i)
	}
	vm.Pop(1)
}


// LOADBOOL指令(iABC模式)给单个寄存器设置布尔值
// R(A) := (bool)B; if (C) pc++
func loadBool(i Instruction, vm api.LuaVM) {

	a, b, c := i.ABC()
	a += 1  // 寄存器数值作为栈索引时需要+1

	vm.PushBoolean(b != 0)
	vm.Replace(a)

	if c != 0 {
		vm.AddPC(1)
	}
}


// `LOADK`指令(iABx模式)将常量表里的某个常量加载到指定寄存器
// R(A) := Kst(Bx)
func loadK(i Instruction, vm api.LuaVM) {

	a, bx := i.ABx()
	a += 1

	vm.GetConst(bx)
	vm.Replace(a)
}


// `LOADKX`指令(也是`iABx`模式)需要和`EXTRAARG`指令(`iAx`模式)搭配使用
// 用后者的`Ax`操作数来指定常量索引.
// `Ax`操作数占26个比特，可以表达的最大无符号整数时67108864，可以满足大部分情况了
func loadKx(i Instruction, vm api.LuaVM) {

	a, _ := i.ABx()
	a += 1

	ax := Instruction(vm.Fetch()).Ax()

	vm.GetConst(ax)
	vm.Replace(a)
}